﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
using System.Collections;
using Lextm.SharpSnmpLib;
using Lextm.SharpSnmpLib.Messaging;
using Lextm.SharpSnmpLib.Security;

namespace GCPUD.Autoprov.Network
{
    public class MacTableEntry : IComparable
    {
        private Mac _mac = new Mac();
        private Vlan _vlan = new Vlan();
        private string _interface = "";
        private string _description = "";
        private string _ifIndex;
        private string _cdpNeighborIp;
        private static SortOrder _order;

        public enum SortOrder
        {
            Ascending = 0,
            Descending = 1
        }
        public MacTableEntry()
            : this(new Mac(), new Vlan { VlanNum = "0" }, "other")
        {
        }
        public MacTableEntry(Mac mac, Vlan vlan)
            : this(mac, vlan, "Other")
        {
        }

        public MacTableEntry(Mac macaddress, Vlan vlan, string interfacename)
        {
            this.macAddress = macaddress;
            this.Vlan = vlan;
            this.Interface = interfacename;
        }
        public string ifIndex
        {
            get
            {
                return this._ifIndex;
            }
            set
            {
                this._ifIndex = value;
            }
        }
        public string cdpNeighborIp
        {
            get
            {
                return this._cdpNeighborIp;
            }
            set
            {
                this._cdpNeighborIp = value;
            }
        }
        public Mac macAddress
        {
            get { return this._mac; }
            set
            {
                if (Mac.IsValid(value))
                {
                    this._mac = value;
                }
            }
        }

        public Vlan Vlan
        {
            get { return this._vlan; }
            set { this._vlan = value; }
        }

        public string Interface
        {
            get { return this._interface; }
            set { this._interface = value; }
        }
        public string Description
        {
            get { return this._description; }
            set { this._description = value; }
        }
        public static SortOrder Order
        {
            get { return _order; }
            set { _order = value; }
        }
        public override int GetHashCode()
        {
            return this._mac.GetHashCode();
        }
        public override bool Equals(Object obj)
        {
            bool retVal = false;
            if (obj != null)
            {
                MacTableEntry macObj = new MacTableEntry();
                macObj = obj as MacTableEntry;
                if ((macObj.macAddress.Equals(this.macAddress)) && (macObj.Vlan.VlanNum.Equals(this.Vlan.VlanNum) && (macObj.Interface.Equals(this.Interface))))
                    retVal = true;
            }
            return retVal;
        }
        public bool EqualsMac(Mac mac)
        {
            bool retVal = false;
            if (mac != null)
            {
                Mac _macAddress = mac;
                if (_macAddress.Equals(this.macAddress))
                    retVal = true;
            }
            return retVal;
        }

        public override string ToString()
        {
            return this.macAddress + ": " + this.Vlan.VlanNum + ": " + this.Interface;
        }

        public int CompareTo(Object obj)
        {
            switch (_order)
            {
                case SortOrder.Ascending:
                    return this.Vlan.CompareTo(((MacTableEntry)obj).Vlan.VlanNum);
                case SortOrder.Descending:
                    return (((MacTableEntry)obj).Vlan.VlanNum).CompareTo(this.Vlan.VlanNum);
                default:
                    return this.Vlan.VlanNum.CompareTo(((MacTableEntry)obj).Vlan.VlanNum);
            }
        }
    }
    public class MacTable : IEnumerable, IComparable, IList
    {
        private int _count = 0;
        private List<MacTableEntry> _macTable;
        public MacTable(List<MacTableEntry> mArray)
        {
            _macTable = new List<MacTableEntry>();

            for (int i = 0; i < mArray.Count; i++)
            {
                _macTable.Add(mArray[i]);
            }
            _count = _macTable.Count;
        }
        public MacTable()
        {
            _macTable = new List<MacTableEntry>();
            
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return (IEnumerator)GetEnumerator();
        }

        public MacTableEnum GetEnumerator()
        {
            return new MacTableEnum(_macTable);
        }
        public List<MacTableEntry> Matches(Mac mac)
        {
            List<MacTableEntry> matchingEntries = new List<MacTableEntry>();
            foreach (MacTableEntry entry in _macTable)
            {
                Debug.WriteLine(entry.macAddress);
                if (entry.macAddress.Equals(mac))
                {
                    matchingEntries.Add(entry);
                }
                Debug.WriteLine(mac);
            }
            return matchingEntries;
        }
        public int Add(Object value)
        {
            _macTable.Add(value as MacTableEntry);
            _count++;
            return (_count - 1);
                
        }
        public void Clear()
        {
            _macTable.Clear();
            _count = 0;
        }
        public bool Contains(object value)
        {
            bool inList = false;
            for (int i = 0; i < Count; i++)
            {
                if (_macTable.Contains(value as MacTableEntry))
                {
                    inList = true;
                    break;
                }
            }
            return inList;
        }
        public int IndexOf(object value)
        {
            return _macTable.IndexOf(value as MacTableEntry);

        }

        public void Insert(int index, object value)
        {
            _macTable.Insert(index, value as MacTableEntry);
        }

        public bool IsFixedSize
        {
            get
            {
                return false;
            }
        }

        public bool IsReadOnly
        {
            get
            {
                return false;
            }
        }

        public void Remove(object value)
        {
            _macTable.Remove(value as MacTableEntry);
        }

        public void RemoveAt(int index)
        {
            _macTable.RemoveAt(index);
        }
        public void CopyTo(object value)
        {
            _macTable.CopyTo(value as MacTableEntry[]);
        }
        public void CopyTo(Array value, int index)
        {
        }

        public int CompareTo(object value)
        {
            return 0;
        }
        public object this[int index]
        {
            get
            {
                return _macTable[index];
            }
            set
            {
                _macTable[index] = value as MacTableEntry;
            }
        }

        // ICollection Members
        public int Count
        {
            get
            {
                return _count;
            }
        }
        public bool IsSynchronized
        {
            get
            {
                return false;
            }
        }
        // Return the current instance since the underlying store is not
        // publicly available.
        public object SyncRoot
        {
            get
            {
                return this;
            }
        }
    }

    public class MacTableEnum : IEnumerator
    {
        public List<MacTableEntry> _macTable;

        // Enumerators are positioned before the first element
        // until the first MoveNext() call.
        int position = -1;

        public MacTableEnum(List<MacTableEntry> list)
        {
            _macTable = list;
        }

        public bool MoveNext()
        {
            position++;
            return (position < _macTable.Count);
        }

        public void Reset()
        {
            position = -1;
        }

        object IEnumerator.Current
        {
            get
            {
                return Current;
            }
        }
        public MacTableEntry Current
        {
            get
            {
                try
                {
                    return _macTable[position];
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }
    }




}
